package com.hursing.tractor.model;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import com.hursing.tractor.view.UIHelper;

public final class Card {
	
	public static final int SUIT_SPADE = 3;
	public static final int SUIT_HEART = 2;
	public static final int SUIT_CLUB = 1;
	public static final int SUIT_DIAMOND = 0;
	public static final int SUIT_JOKER = 4;
	public static final int SUIT_TRUMP = 4;				// 主牌
	public static final int SUIT_COUNT = 5;
	public static final int SUIT_COUNT_WITHOUT_JOKER = 4;
	public static final int SUIT_UNKNOWN = -1;
	
	public static final int NUMBER_BLACK = 0;
	public static final int NUMBER_RED = 1;
	public static final int NUMBER_2 = 0;
	public static final int NUMBER_5 = 3;
	public static final int NUMBER_10 = 8;
	public static final int NUMBER_K = 11;
//	public static final int NUMBER_A = 12;
	public static final int NUMBER_COUNT = 13;
	public static final int MAX_NUMBER_IN_VICE = 12;
	
	public static final int COUNT_OF_ONE_DECK = 54;
	public static final int COUNT_OF_ONE_DECK_WITHOUT_JOKER = 52;
	public static final int COUNT_OF_ONE_SUIT = 13;
	public static final int COUNT_OF_JOKER = 2;
	public static final int COUNT_OF_SUIT_TYPE = 5;
	
	private final int mSuit;	// 花色
	private final int mNumber;	// 牌值
	private final int mIndex;	// 牌在mCardCollection中的下标，从方块2到A，方块到黑桃到小王、大王
	private final int mMark;	// 分值
	private int mHeight;	// 大小。比master大的牌height比number小1。副主为12,正主为13,小王14,大王15，无主时主都为13
	private int mDisplayOrder;	// 显示顺序的排序。主牌的order比index大52。副主比index大200,正主大300。小王是400,大王是500。按此规则，大于等于52的就是主牌,大于等于200是必然是主的牌。
	
	public static final Card largeJoker;		// 大王
	public static final Card smallJoker;	// 小王
	/** 
	 * 保存一副牌的数组，实现每个Card都是单例。
	 */
	private static final Card[] mCardCollection = new Card[COUNT_OF_ONE_DECK];
	static {
		for (int i = 0; i < COUNT_OF_ONE_DECK; i++) {
			mCardCollection[i] = new Card(i);
		}
		largeJoker = Card.getCard(SUIT_JOKER, NUMBER_RED);
		largeJoker.mDisplayOrder = 500;
		smallJoker = Card.getCard(SUIT_JOKER, NUMBER_BLACK);
		smallJoker.mDisplayOrder = 400;
	}
	
	public static void getAllCards(List<Card> container) {
		getCards(container, GameData.instance().deckCount());
	}
	
	public static void getCards(List<Card> container, int deckCount) {
		container.clear();
		while((deckCount--) > 0) {
			container.addAll(Arrays.asList(mCardCollection));
		}
	}

	public static Card getCard(int index) {
		return mCardCollection[index];
	}
	
	public static Card getCard(int suit, int number) {
		return getCard(calcValue(suit, number));
	}
	
	private static int calcValue(int suit, int number) {
		return suit * COUNT_OF_ONE_SUIT + number;
	}
	
	private Card(int index) {
		mIndex = index;
		mSuit = index / COUNT_OF_ONE_SUIT;
		mNumber = index % COUNT_OF_ONE_SUIT;
		if (mNumber == NUMBER_K || mNumber == NUMBER_10) {
			mMark = 10;
		} else if (mNumber == NUMBER_5) {
			mMark = 5;
		} else {
			mMark = 0;
		}
	}
	
	public int suit() {
		return mSuit;
	}
	
	public int number() {
		return mNumber;
	}
	
	public int mark() {
		return mMark;
	}
	
	public int height() {
		return mHeight;
	}
	
	public int index() {
		return mIndex;
	}
	
	/**
	 * 是否比牌大
	 * @param card
	 * @return
	 */
	public boolean isLargerThanOther(Card card) {
		if (this.suitDistinguishTrump() == card.suitDistinguishTrump()) {
			return this.mHeight > card.mHeight;
		} else {
			// 如果自己不是主牌，则一定是对方大
			return this.isTrump();
		}
	}
	
	public boolean isTrump() {
		return mDisplayOrder >= COUNT_OF_ONE_DECK_WITHOUT_JOKER;
	}
	
	public boolean isCerternTrump() {
		return mDisplayOrder >= 200;
	}
	
	public int suitDistinguishTrump() {
		return isTrump() ? SUIT_TRUMP : mSuit;
	}
	
	@Override
	public int hashCode() {
		return mIndex;
	}
	
	// 测试用
	private static String[] suitText = {"方块", "梅花", "红桃", "黑桃", "大王"};
	@Override
	public String toString() {
		return suitText[mSuit] + UIHelper.numberToText(mNumber);
	}

	public static void sortForDisplay(List<Card> list) {
		Collections.sort(list, new Comparator<Card>() {
			@Override
			public int compare(Card lhs, Card rhs) {
				return rhs.mDisplayOrder - lhs.mDisplayOrder;
			}
		});
	}
	
	public static void sortForHeight(List<Card> list) {
		Collections.sort(list, new Comparator<Card>() {
			@Override
			public int compare(Card lhs, Card rhs) {
				// 副主的height相等，按suit来排序
				if (rhs.mHeight == lhs.mHeight) {
					return rhs.mSuit - lhs.mSuit;
				} else {
					return rhs.mHeight - lhs.mHeight;
				}
			}
		});
	}

	public static void calculateCardOrder() {
		for (int i = 0; i < 52; i++) {
			Card card = mCardCollection[i];
			if (card.mSuit == GameData.instance().getFlippedSuit()) {
				card.mDisplayOrder = card.mIndex + 52;
			} else {
				card.mDisplayOrder = card.mIndex;
			}
			if (card.mNumber == GameData.instance().getCurrentMaster()) {
				if (card.mSuit == GameData.instance().getFlippedSuit()) {
					card.mHeight = 13;
					card.mDisplayOrder = card.mIndex + 300;
				} else {
					card.mHeight = 12;
					card.mDisplayOrder = card.mIndex + 200;
				}
			} else if (card.mNumber > GameData.instance().getCurrentMaster()) {
				card.mHeight = card.mNumber - 1;
			} else {	// card.mNumber < GameData.instance().getCurrentMaster()
				card.mHeight = card.mNumber;
			}
		}

		if (GameData.instance().getFlippedSuit() != SUIT_JOKER && GameData.instance().getFlippedSuit() != SUIT_UNKNOWN) {
			smallJoker.mHeight = 14;
			largeJoker.mHeight = 15;
		} else {
			smallJoker.mHeight = 13;
			largeJoker.mHeight = 14;
		}
	}

}
